/**
 * Crazy Query
 *  License by CrazyYi.
 *  v1.0.0 20200206
 *
 *  Only use for table query
 *
 */
layui.define(['table', 'jquery', 'crazyTool'], function (exports) {
    const MOD_NAME = 'crazyTableQuery'

    const TABLE_MAIN = '.layui-table-main',
        TABLE_BOX = '.layui-table-box',
        TABLE_TOTAL = '.layui-table-total',
        TABLE_HEADER = '.layui-table-header',
        TABLE_BODY = '.layui-table-body',
        TABLE_CELL = '.layui-table-cell',
        TABLE_FIXED = '.layui-table-fixed',
        TABLE_PAGE = '.layui-table-page',
        TABLE_TOOL = '.layui-table-tool'

    const BODY = 'body',
        HIDE = 'layui-hide';

    let $ = layui.jquery,
        table = layui.table,
        $Tool = layui.crazyTool

    let gRes;
    let gTotalRow = {};
    let gElem; // 保存 table 的elem，注意是HTML结构，是table.render done回调函数中的 this
    let gTbId; // 保存 table id
    let gMainTable = {};

    /** Layui Table 结构
     *
     *  <div id="YourTableID">                          --- tbElem(), tbFilter()
     *  <div lay-id="YourTableID">                      --- tbNext()
     *      <div layui-table-tool>                      --- tbTool()
     *
     *      <div layui-table-box>                       --- tbBox()
     *          <div layui-table-header>                --- tbHeader()
     *              <table>                             --- header table
     *                  <thead>                         --- header thead, getTh(field), getThCell(th)
     *
     *          <div layui-table-body layui-table-main> --- tbMain()
     *              <table>                             --- main table
     *                  <tbody>                         --- main tbody
     *                      <tr data-index="0">...<tr>  --- main tr, getTrs(), getTr(rowIndex)
     *                          <td data-field="xxx">   --- main td, getTds(field), getTd(field, index), getTdsValue(field)
     *                                                  --- getTdCell(td), getTdValue(td)
     *
     *          <div layui-table-fixed>                 --- tbFixed()
     *              <div layui-table-header>            --- *** the other header
     *              <div layui-table-body>              --- *** the other body
     *
     *      <div layui-table-total>                     --- tbTotal()
     *          <table>                                 --- total table, getTotalTds(field)
     *
     *      <div layui-table-page>                      --- tbPage()
     *
     *  注意：
     *      1. 有两个 .layui-table-body，一个是主表body，一个是固定列的body。如果只查询这个class，会把两个都查询出来。
     *      2. 因此要查询主表body，应该查询 .layui-table-main。
     */

    /**
     * 保存 table 的主要参数
     * @type {{
     *          render: (function(): (*)),
     *          reload: (function(): (*)),
     *          elem: undefined,
     *          id: undefined,
     *
     *          tbElem: (function(): (jQuery|HTMLElement)),
     *          tbId: (function(): (jQuery|HTMLElement)),
     *          tbFilter: (function(): (String)),
     *          htmlBody: (function(): (jQuery|HTMLElement)),
     *          tbNext: (function(): (jQuery|HTMLElement)),
     *          tbHeader: (function(): (jQuery|HTMLElement)),
     *          tbMain: (function(): (jQuery|HTMLElement)),
     *          tbTotal: (function(): (jQuery|HTMLElement)),
     *
     *          getTds: (function(): (jQuery|HTMLElement)),
     *          getTdsValue: (function(): (Array)),
     *          getTh: (function(): (jQuery|HTMLElement)),
     *          getTotalTds: (function(): (jQuery|HTMLElement)),
     *          getTrs: (function(): (jQuery|HTMLElement)),
     *          getTd: (function(): (jQuery|HTMLElement)),
     *          getEachTds: (function(): (jQuery|HTMLElement)),
     *          getTdValue: (function(): (jQuery|HTMLElement)),
     *          getThCell: (function(): (jQuery|HTMLElement)),
     *          getTdCell: (function(): (jQuery|HTMLElement)),
     *          getTrByCell: (function(): (jQuery|HTMLElement)),
     *
     *          filter: (function(): ()),
     *          updateTotal: (function(): ()),
     *          resize: (function(): ()),
     *          checkStatus: (function(): (Array)),
     *          getCheckedTrs: (function(): (Array)),
     *
     *        }}
     */
    let gTable = {
        render: function (myTable, res) {
            gMainTable = myTable;
            gElem = myTable.elem;
            gTbId = $(elem).attr('id');

            gRes = res || {};
            gTotalRow = gRes.totalRow || {};
        },
        reload: function (where) {
            table.reload(this.tbId(), where);
        },

        htmlBody: function () { return $(BODY); },

        tbElem: function () { return $(gElem); },
        tbId: function () { return gTbId; },
        tbFilter: function () {return this.tbElem().attr('lay-filter') },
        // tbNext: 主表区域
        tbNext: function () { return this.tbElem().next() },

        tbTool: function () { return this.tbNext().children(TABLE_TOOL) },
        tbBox: function () { return this.tbNext().find(TABLE_BOX) },
        tbPage: function () { return this.tbNext().find(TABLE_PAGE);},
        tbTotal: function () { return this.tbNext().find(TABLE_TOTAL);},

        tbHeader: function () { return this.tbBox().find(TABLE_HEADER) },
        tbMain: function () { return this.tbBox().find(TABLE_MAIN)},
        tbFixed: function () { return this.tbBox().find(TABLE_FIXED);},

        // 会包括主表body，以及fixed body两个部分
        tbBody: function () { return this.tbNext().children(TABLE_BODY) },

        getTds: function (field) {
            if (!this.tbNext()) { return null; }
            return this.tbMain().find(`td[data-field="${field}"]`);
        },
        getTdsValue: function (field) {
            if (!this.tbNext()) { return null; }
            let tds = this.getTds(field);
            return this.getEachTds(tds);
        },
        getTh: function (field) {
            return this.tbHeader().find(`th[data-field="${field}"]`);
        },
        getTotalTds: function (field) {
            return this.tbTotal().find(`td[data-field="${field}"]`);
        },
        getTrs: function () {
            return this.tbMain().find('tr');
        },
        getTd: function (field, index) {
            if (!this.tbNext()) { return null; }
            return this.tbMain().find(`td[data-field="${field}"]`).eq(index);
        },
        /**
         * 遍历行获取本地列集合 return tdsArray[]
         * @param tds
         * @returns {Array}
         */
        getEachTds: function (tds) {
            let tdsText = [],
                tdsArray = [];
            tds.each(function (i, td) {
                let curV = this.getTdValue(td);
                tdsText.push($.trim(curV))
            });
            tdsText = $Tool.uniqueObjArray(tdsText);
            $.each(tdsText, function (i, item) {
                tdsArray.push({'key': item, 'value': item})
            });
            return tdsArray;
        },
        getTdValue: function (td) {
            let curV = '';
            if ($(td).length <= 0) {return ''}
            if ($(td).find('input').length > 0) {
                curV = $(td).find('input').val()
            } else {
                curV = $(td).text();
            }
            return $.trim(curV);
        },
        getThCell: function (th) {
            return th.find(TABLE_CELL)
        },
        getTdCell: function (td) {
            return td.find(TABLE_CELL)
        },
        getTr: function (index) {
            return this.tbMain().children(`tr[data-index="${index}"]`);
        },

        filter: function (trsIndex) {
            console.log('curr show indexs =', trsIndex)

            // 本地缓存 和 options配置项 交叉比对
            let trs = this.getTrs();
            if (trsIndex.length > 0) {
                trs.each(function (i, tr) {
                    if ($.inArray($(tr).data("index"), trsIndex) !== -1) {
                        $(tr).removeClass(HIDE)
                    } else {
                        $(tr).addClass(HIDE)
                    }
                })
            } else {
                trs.removeClass(HIDE)
            }

            (!!($(TABLE_TOTAL).length)) && this.updateTotal(); // 更新合计行
            this.resize(); // 重载表格尺寸
        },
        updateTotal: function () {
            let othis = this;
            let elemId = othis.tbId();
            table.eachCols(elemId, function (i, item) {
                if (item.totalRow) {
                    let iSum = 0;
                    let tds = othis.getTds(item.field);
                    $.each(tds, function (i, td) {
                        if (!$(td).parent().hasClass(HIDE)) {
                            //FIX JS计算精度
                            iSum = (iSum * 10 + Number($.trim(td.innerText)) * 10) / 10
                        }
                    });
                    let totalTds = othis.getTotalTds(item.field);
                    totalTds.each(function (i, td) {
                        $(td).find(TABLE_CELL).html(iSum || "0")
                    });
                }
            });

            // Layui2.5.6 新增在parseData中增加totalRow，因此这里需要对这部分单独进行处理
            // 目前，仅支持计算有多少条记录。暂不支持其他
            if (gTotalRow) {
                $.each(gTotalRow, function (key, value) {
                    let iSum = 0;
                    let tds = othis.getTds(key);
                    $.each(tds, function (i, td) {
                        if (!$(td).parent().hasClass(HIDE)) {
                            iSum++
                        }
                    });
                    let totalTds = othis.getTotalTds(key);
                    totalTds.each(function (i, td) {
                        $(td).find(TABLE_CELL).html(iSum || "0")
                    });
                });
            }
        },
        resize: function () { table.resize(this.tbId()); },
        checkStatus: function () {
            return table.checkStatus(this.tbId()); // 获取当前选中的行的记录
        },
        getKeys: function () {
            let checkStatus = this.checkStatus();
            let rows = checkStatus.data;

            let ids = [];
            let key = gRes.pkey.field;
            for (let i in rows) {
                if (rows.hasOwnProperty(i)) {
                    ids.push(rows[i][key]);
                }
            }
        },

        getTrByCell: function (cell) {
            return $(cell).parent('tr');
        },

        getCheckedTrs: function () {
            let pkey = gRes.pkey;
            let field = pkey.field;
            let othis = this;
            let checkStatus = table.checkStatus(this.tbId());
            let rows = checkStatus.data;
            if (!rows.length) {
                return false;
            }

            let trs = this.getTrs(), trArr = {};
            // console.log('trs', trs);
            $.each(rows, function (i, row) {
                $.each(trs, function (i, tr) {
                    let td = $(tr).find(`td[data-field="${field}"]`)[0];
                    // console.log('td=>', td);
                    let curK = row[field]; // 当前行的key值
                    let tdV = othis.getTdValue(td);
                    // console.log('curK=>', curK, 'tdV=>', tdV);
                    if ($Tool.compare(tdV, curK)) {
                        trArr[curK] = tr;
                        return false; // 找到对应行，退出本次循环
                    }
                })
            });
            console.log('checked status tr array =>', trArr)
            return trArr;
        },
    };

    /**
     * 输出接口 gTable
     */
    exports(MOD_NAME, gTable);
});